package org.vison.wonfu.framework.commons.utils;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Future;

public class TypeUtils {
    // 基本类型集合
    private static final Set<Class<?>> PRIMITIVE_TYPES = new HashSet<>(Arrays.asList(
            byte.class, short.class, int.class, long.class,
            float.class, double.class, boolean.class, char.class
    ));

    // 包装类集合
    private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<>(Arrays.asList(
            Byte.class, Short.class, Integer.class, Long.class,
            Float.class, Double.class, Boolean.class, Character.class
    ));


    public static boolean isPrimitives(Class<?> cls) {
        while (cls.isArray()) {
            cls = cls.getComponentType();
        }
        return isPrimitive(cls);
    }

    // 判断是否为基本类型
    public static boolean isPrimitive(Class<?> clazz) {
        return clazz != null && clazz.isPrimitive();
    }

    // 判断是否为包装类
    public static boolean isWrapper(Class<?> clazz) {
        return WRAPPER_TYPES.contains(clazz);
    }

    // 判断是否为基本类型或包装类
    public static boolean isPrimitiveOrWrapper(Class<?> clazz) {
        return clazz != null && (clazz.isPrimitive() || WRAPPER_TYPES.contains(clazz));
    }



    // 判断是否为基本类型数组（如 int[]、boolean[]）
    public static boolean isPrimitiveArray(Class<?> clazz) {
        return clazz != null && clazz.isArray() && clazz.getComponentType().isPrimitive();
    }

    // 获取基本类型对应的包装类
    public static Class<?> getWrapperType(Class<?> primitiveType) {
        if (!primitiveType.isPrimitive()) {
            return primitiveType;
        }

        if (int.class == primitiveType) return Integer.class;
        if (boolean.class == primitiveType) return Boolean.class;
        if (long.class == primitiveType) return Long.class;
        if (double.class == primitiveType) return Double.class;
        if (float.class == primitiveType) return Float.class;
        if (char.class == primitiveType) return Character.class;
        if (byte.class == primitiveType) return Byte.class;
        if (short.class == primitiveType) return Short.class;

        return primitiveType;
    }

    /**
     * 返回类型为Future或其泛型子类时，能够进一步解析出其实际的泛型参数类型。这对于在异步编程或远程服务调用
     * （如SOA架构）中，正确地处理返回结果至关重要。
     * @param returnType
     * @param genericReturnType
     * @return
     */
    public static Type[] getReturnTypes(Class<?> returnType, Type genericReturnType) {
        if (Future.class.isAssignableFrom(returnType)) {
            if (genericReturnType instanceof ParameterizedType) {
                Type actualArgType = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0];
                if (actualArgType instanceof ParameterizedType) {
                    returnType = (Class<?>) ((ParameterizedType) actualArgType).getRawType();
                    genericReturnType = actualArgType;
                } else if (actualArgType instanceof TypeVariable) {
                    returnType = (Class<?>) ((TypeVariable<?>) actualArgType).getBounds()[0];
                    genericReturnType = actualArgType;
                } else {
                    returnType = (Class<?>) actualArgType;
                    genericReturnType = returnType;
                }
            } else {
                returnType = null;
                genericReturnType = null;
            }
        }
        return new Type[]{returnType, genericReturnType};
    }

    public JavaType convertToJavaType(Type type) {
        if (type == null) {
            return TypeFactory.defaultInstance().constructType(Object.class);
        }
        TypeFactory factory = TypeFactory.defaultInstance();
        // 处理原始Class类型
        if (type instanceof Class<?>) {
            return factory.constructType(type);
        } else if (type instanceof ParameterizedType) {
            return factory.constructType(type);
        } else if (type instanceof GenericArrayType) {
            return factory.constructType(type);
        } else if (type instanceof TypeVariable<?>) {
            TypeVariable<?> typeVar = (TypeVariable<?>) type;
            // 获取类型变量的边界（如<T extends Number>）
            Type[] bounds = typeVar.getBounds();
            if (bounds.length > 0) {
                return factory.constructType(bounds[0]);
            } else {
                return factory.constructType(Object.class); // 默认边界为Object
            }
        } else if (type instanceof WildcardType) {
            WildcardType wildcardType = (WildcardType) type;
            Type[] upperBounds = wildcardType.getUpperBounds();
            if (upperBounds.length > 0) {
                return factory.constructType(upperBounds[0]);
            }
            return factory.constructType(Object.class);
        }

        // 未知类型，返回Object
        return factory.constructType(Object.class);
    }
}